package glassline;

import glassline.interfaces.Popup;
import glassline.interfaces.Workstation;
import agent.*;
import transducer.*;

public class WorkstationAgent extends Agent implements Workstation, TReceiver
{
	/*
	 * Data
	 */
	private Popup pop;//associated popup
	private Glass glassToWorkOn;//the glass to work on
	private Glass glassToSend;//the glass being sent
	private Boolean busy;//if workstation is working on a glass
	private Boolean on;// turn workstation on or off
	private Boolean readyToSend;// tells the workstation popup is ready for glass
	private Boolean askToCome; //tells the popup to come up
	private Transducer t;
	private Glass.WorkStation type;//type of workstation CrossSeamer... etc..
	private int id;//workstation id to identify transducer messages
	private String name;
	
	/*Constructor
	 * 
	 * Initializes all data
	 */
	public WorkstationAgent(Popup p, Transducer trans, Glass.WorkStation ty, int ids)
	{
		super();
		pop = p;
		t = trans;
		on = true;
		busy = false;
		readyToSend = false;
		t.register(this, TChannel.WORKSTATION);
		type = ty;
		id = ids;
		askToCome = false;
		name = "Workstation " + id;
	}
	
	/* (non-Javadoc)
	 * @see glassline.Workstation#msgHereIsGlass(glassline.Glass)
	 */
	@Override
	public void msgHereIsGlass(Glass g)
	{
		glassToWorkOn = g;
		busy = true;
		print("Glass Recieved");
		stateChanged();
	}
	/* (non-Javadoc)
	 * @see glassline.Workstation#msgIAmUp()
	 */
	@Override
	public void msgIAmUp()
	{
		readyToSend = true;
		stateChanged();
		print("popup is ready");
		stateChanged();
	}
	/*method turnOnOff()
	 * 
	 * switches on boolean to turn on or off the workstation
	 */
	public void turnOnOff()
	{
		if(on == true)
		{
			on = false;
		}
		else
		{
			on = true;
		}
	}
	/*
	 * (non-Javadoc)
	 * @see agent.Agent#pickAndExecuteAnAction()
	 * 
	 * Scheduler
	 * 
	 * determines logic. if there is a glass to work on, do work on glass
	 * if need to ask popup to come up, ask to come
	 * if glass is ready to send send a glass back to the popup
	 */
	@Override
	public boolean pickAndExecuteAnAction() {
		if(glassToWorkOn != null)
		{
			doWorkOnGlass(glassToWorkOn);
			return true;
		}
		if(askToCome == true)
		{
			askToCome();
			return true;
		}
		if(readyToSend == true)
		{
			sendGlass(glassToSend);
			return true;
		}
		
		return false;
	}
	/*
	 *			Actions 
	 */
	/*method askToCome()
	 * 
	 * asks the poup to come up
	 */
	public void askToCome()
	{
		print("asking popup to come up");
		askToCome = false;
		pop.msgComeUp(this);
		stateChanged();
	}
	/*method doWorkOnGlass(Glass g)
	 * 
	 * does animation on glass g sets glass g to the glass to send
	 */
	public void doWorkOnGlass(Glass g)
	{
		glassToSend = g;
		doAnimateWork(g);
		print("working on glass");
		stateChanged();
		
	}
	/*method sendGlass(Glass g)
	 * 
	 * sends glass back to popup
	 */
	public void sendGlass(Glass g)
	{
		readyToSend = false;
		glassToSend = null;
		print("sending glass");
		pop.msgHereIsGlass(g,this);
		stateChanged();
	}
	/*doAnimateWork(Glass g)
	 * 
	 * does the animation, tells glass it has been worked on
	 */
	public void doAnimateWork(Glass g)
	{
		Object array[] = {id};
		glassToWorkOn = null;
		t.fireEvent(TChannel.WORKSTATION, TEvent.WORKSTATION_ANIMATE_START,array);
		g.recipe.workstations.put(type, true);
	}
	/*
	 * (non-Javadoc)
	 * @see transducer.TReceiver#eventFired(transducer.TChannel, transducer.TEvent, java.lang.Object[])
	 * 
	 * listens to when animation is finished and then sets askToCome to true to ask popup to come
	 */
	@Override
	public void eventFired(TChannel channel, TEvent event, Object[] args) 
	{
		if(channel == TChannel.WORKSTATION)
		{
			if(event == TEvent.WORKSTATION_ANIMATE_DONE)
			{
				if(((Integer)args[0]) == id)
				{
					busy = false;
					askToCome = true;
					stateChanged();
				}
			}
		}
		
	}
	/*
	 * (non-Javadoc)
	 * @see java.lang.Object#toString()
	 * return name
	 */
	public String toString()
	{
		return name;
	}
	/*
	 * (non-Javadoc)
	 * @see glassline.interfaces.Workstation#getType()
	 */
	public Glass.WorkStation getType()
	{
		return type;
	}
}
